﻿using System;

namespace ZquenceStudio3Host.DspPlugins.Synthesizers.Nodesizer.Engine.Modules.LowLevel
{
    [ModuleDisplay("Exp")]
    public class ExpModule : BaseModule
    {
        public readonly ModuleInput Exp;
        public readonly ModuleOutput Out;

        public ExpModule(ModuleManager manager)
            : base(manager)
        {
            // Add input and outputs to module.
            AddInput(Exp = new ModuleInput("Exp", IOType.AudioOrWaveform, this));
            AddOutput(Out = new ModuleOutput("Out", IOType.AudioOrWaveform, this));
        }

        public override void Process()
        {
            if (Exp.IsConnected)
            {
                for (int i = 0; i < Out.AudioBuffer.Length; i++)
                {
                    Out.AudioBuffer[i] = Exponential(Exp.FromOutput.AudioBuffer[i]) - 1.0;
                }
            }
        }

        /// <summary>
        /// Reference: http://martin.ankerl.com/2007/10/04/optimized-pow-approximation-for-java-and-c-c/
        /// Tips? http://stackoverflow.com/questions/10552280/fast-exp-calculation-possible-to-improve-accuracy-without-losing-too-much-perfo
        /// </summary>
        /// <param name="val"></param>
        /// <returns></returns>
        public static double Exponential(double val)
        {
            long tmp = (long)(1512775 * val + (1072693248 - 60801));
            return BitConverter.Int64BitsToDouble(tmp << 32);
        }
    }
}
